﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using WINADM.Data;
using WINADM.Server;
using System.Data.Objects;
using log4net;
namespace WINADM.Server.Test
{
    [TestClass]
    public class ControllerTests
    {
        Mock<IEntityRepository> _entityRepositoryMock;
        Mock<IObjectSet<Computer>> _computerObjectSet;
        Mock<ILog> _loggerMock;
        Mock<ISystemInfo> _systemInfoMock;
        FakeObjectSet<Computer> _fakeComputerObjectSet;

        [TestInitialize()]
        public void Initialize()
        {
            _entityRepositoryMock = new Mock<IEntityRepository>(MockBehavior.Strict);
            _computerObjectSet = new Mock<IObjectSet<Computer>>(MockBehavior.Strict);
            _loggerMock = new Mock<ILog>(MockBehavior.Strict);
            _systemInfoMock = new Mock<ISystemInfo>(MockBehavior.Strict);
            _fakeComputerObjectSet=new FakeObjectSet<Computer>();

        }

        [TestMethod]
        public void TestRegisterComputerForRegisteredComputerUpdateSuccess()
        {
            Computer comp = new Computer();
            comp.ComputerName = "ILOSPAHHGQQM-L";
            comp.LastHeartBeat = System.DateTime.Now;
            _fakeComputerObjectSet.AddObject(comp);

            _systemInfoMock.Setup(x => x.MachineName).Returns("ILOSPAHHGQQM-L").Verifiable();
            _loggerMock.Setup(x => x.Info("Retrieving registeration info for computer ILOSPAHHGQQM-L...")).Verifiable();
            _entityRepositoryMock.Setup(x => x.Computers).Returns(_fakeComputerObjectSet).Verifiable();
            _loggerMock.Setup(x => x.Info("ILOSPAHHGQQM-L is already registered. Updating LastHeartBeat time.")).Verifiable();
            _systemInfoMock.Setup(x => x.TimeStamp).Returns(new DateTime(2012,05,05,05,05,05)).Verifiable();
            _entityRepositoryMock.Setup(x => x.SaveChanges()).Returns(1).Verifiable();
            _loggerMock.Setup(x => x.Info("ILOSPAHHGQQM-L LastHeartBeat time updated successfully.")).Verifiable();

            Controller controller = new Controller(_entityRepositoryMock.Object, _loggerMock.Object, _systemInfoMock.Object);
            bool result = controller.RegisterComputer();
            Assert.AreEqual(new DateTime(2012, 05, 05, 05, 05, 05), comp.LastHeartBeat);
            Assert.AreEqual(true, result);

            _systemInfoMock.VerifyAll();
            _loggerMock.VerifyAll();
            _entityRepositoryMock.Verify(x => x.SaveChanges(), Times.Once());
        }

        [TestMethod]
        public void TestRegisterComputerForRegisteredComputerUpdateFailure()
        {
            Computer comp = new Computer();
            comp.ComputerName = "ILOSPAHHGQQM-L";
            comp.LastHeartBeat = System.DateTime.Now;
            _fakeComputerObjectSet.AddObject(comp);

            _systemInfoMock.Setup(x => x.MachineName).Returns("ILOSPAHHGQQM-L").Verifiable();
            _loggerMock.Setup(x => x.Info("Retrieving registeration info for computer ILOSPAHHGQQM-L...")).Verifiable();
            _entityRepositoryMock.Setup(x => x.Computers).Returns(_fakeComputerObjectSet).Verifiable();
            _loggerMock.Setup(x => x.Info("ILOSPAHHGQQM-L is already registered. Updating LastHeartBeat time.")).Verifiable();
            _systemInfoMock.Setup(x => x.TimeStamp).Returns(new DateTime(2012, 05, 05, 05, 05, 05)).Verifiable();
            _entityRepositoryMock.Setup(x => x.SaveChanges()).Returns(0).Verifiable();
            _loggerMock.Setup(x => x.Info("ILOSPAHHGQQM-L LastHeartBeat time update unsuccessfull.")).Verifiable();

            Controller controller = new Controller(_entityRepositoryMock.Object, _loggerMock.Object, _systemInfoMock.Object);
            bool result = controller.RegisterComputer();

            Assert.AreEqual(false, result);

            _systemInfoMock.VerifyAll();
            _loggerMock.VerifyAll();
            _entityRepositoryMock.VerifyAll();
        }

        [TestMethod]
        public void TestRegisterComputerForNewComputerUpdateSuccess()
        {
            Computer comp = new Computer();
            comp.ComputerName = "ILOSPAHHGQQM-D";
            comp.LastHeartBeat = System.DateTime.Now;
            _fakeComputerObjectSet.AddObject(comp);

            _systemInfoMock.Setup(x => x.MachineName).Returns("ILOSPAHHGQQM-L").Verifiable();
            _loggerMock.Setup(x => x.Info("Retrieving registeration info for computer ILOSPAHHGQQM-L...")).Verifiable();
            _entityRepositoryMock.Setup(x => x.Computers).Returns(_fakeComputerObjectSet).Verifiable();
            _loggerMock.Setup(x => x.Info("ILOSPAHHGQQM-L is not registered. Registering for first time.")).Verifiable();
            _loggerMock.Setup(x => x.Debug("Following registered computers found...")).Verifiable();
            _loggerMock.Setup(x => x.Debug("ILOSPAHHGQQM-D")).Verifiable();
             _systemInfoMock.Setup(x => x.TimeStamp).Returns(new DateTime(2012, 05, 05, 05, 05, 05)).Verifiable();
            _entityRepositoryMock.Setup(x => x.SaveChanges()).Returns(1).Verifiable();
            _loggerMock.Setup(x => x.Info("ILOSPAHHGQQM-L registered successfully.")).Verifiable();

            Controller controller = new Controller(_entityRepositoryMock.Object, _loggerMock.Object, _systemInfoMock.Object);
            bool result = controller.RegisterComputer();

            Assert.AreEqual(2, _fakeComputerObjectSet.Count<Computer>());
            Computer resComp = _fakeComputerObjectSet.Single(x => x.ComputerName == "ILOSPAHHGQQM-L");
            Assert.AreEqual("ILOSPAHHGQQM-L", resComp.ComputerName);
            Assert.AreEqual(new DateTime(2012, 05, 05, 05, 05, 05), resComp.LastHeartBeat);
            Assert.AreEqual(true, result);

            _systemInfoMock.VerifyAll();
            _loggerMock.VerifyAll();
            _entityRepositoryMock.VerifyAll();
        }

        [TestMethod]
        public void TestRegisterComputerForNewComputerUpdateFailure()
        {
            Computer comp = new Computer();
            comp.ComputerName = "ILOSPAHHGQQM-D";
            comp.LastHeartBeat = System.DateTime.Now;
            _fakeComputerObjectSet.AddObject(comp);

            _systemInfoMock.Setup(x => x.MachineName).Returns("ILOSPAHHGQQM-L").Verifiable();
            _loggerMock.Setup(x => x.Info("Retrieving registeration info for computer ILOSPAHHGQQM-L...")).Verifiable();
            _entityRepositoryMock.Setup(x => x.Computers).Returns(_fakeComputerObjectSet).Verifiable();
            _loggerMock.Setup(x => x.Info("ILOSPAHHGQQM-L is not registered. Registering for first time.")).Verifiable();
            _loggerMock.Setup(x => x.Debug("Following registered computers found...")).Verifiable();
            _loggerMock.Setup(x => x.Debug("ILOSPAHHGQQM-D")).Verifiable();
            _systemInfoMock.Setup(x => x.TimeStamp).Returns(new DateTime(2012, 05, 05, 05, 05, 05)).Verifiable();
            _entityRepositoryMock.Setup(x => x.SaveChanges()).Returns(0).Verifiable();
            _loggerMock.Setup(x => x.Info("ILOSPAHHGQQM-L registeration unsuccessfull.")).Verifiable();

            Controller controller = new Controller(_entityRepositoryMock.Object, _loggerMock.Object, _systemInfoMock.Object);
            bool result = controller.RegisterComputer();

            Assert.AreEqual(2, _fakeComputerObjectSet.Count<Computer>());
            Computer resComp = _fakeComputerObjectSet.Single(x => x.ComputerName == "ILOSPAHHGQQM-L");
            Assert.AreEqual("ILOSPAHHGQQM-L", resComp.ComputerName);
            Assert.AreEqual(new DateTime(2012, 05, 05, 05, 05, 05), resComp.LastHeartBeat);
            Assert.AreEqual(false, result);

            _systemInfoMock.VerifyAll();
            _loggerMock.VerifyAll();
            _entityRepositoryMock.VerifyAll();
        }

        [TestCleanup]
        public void Cleanup()
        {
           

        }
    }
}
